package com.yangcangclub.trade.domain;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yangcangclub.commons.exception.ApolloException;
import com.yangcangclub.commons.result.MessageEnum;
import com.yangcangclub.trade.base.TradeBaseDomain;
import com.yangcangclub.trade.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by user on 2017/2/27.
 */
@Component
public class TradeDomain extends TradeBaseDomain {

    @Autowired
    private TradeAddressDomain tradeAddressDomain;
    @Autowired
    private TradeDetailsDomain tradeDetailsDomain;
    @Autowired
    private TradeReqLogsDomain tradeReqLogsDomain;
    @Autowired
    private  TradeRefundDomain tradeRefundDomain;

    /**
     * 保存订单基本信息
     * @param tradeSummary
     * @return
     * */
    public int insertTrade(TradeSummary tradeSummary){
        super.getMasterJdbc().insert("trade.TradeMapper.insertTrade",tradeSummary);
        int id = tradeSummary.getId();
        if(id == 0){
            //回滚
            throw new ApolloException(MessageEnum.ORDER_ADD_FAILURE);
        }
        return id;
    }
    /**
     * 更新订单信息
     * @param updateType
     * @param id
     * @param tradeNo
     * @param userId
     * @param updateInfo {express,contact,other}
     * @param lastUpdateUserId
     * @return*/
    public int updateTrade(String updateType, int id,String tradeNo, int userId, JSONObject updateInfo, int lastUpdateUserId){
        Map m = Maps.newHashMap();
        m.put("id",id);
        m.put("lastUpdateUserId",lastUpdateUserId);
        m.put("lastUpdateDate",new Date());
        //更新物流信息
        if("express".equals(updateType)){
            m.put("expressName",updateInfo.getString("expressName"));
            m.put("expressId",updateInfo.getString("expressId"));
            m.put("expressNo",updateInfo.getString("expressNo"));
            m.put("expressUpdateDate",new Date());
            m.put("serviceRemark",updateInfo.getString("serviceRemark"));
            m.put("status","R");//变更为已发货状态
        }
        //更新地址信息
        if("contact".equals(updateType)){
            TradeAddress tradeAddress = new TradeAddress();
            tradeAddress.setUserId(userId);
            tradeAddress.setCreateDate(new Date());
            tradeAddress.setTradeNo(tradeNo);
            tradeAddress.setProvince(updateInfo.getString("province"));
            tradeAddress.setCity(updateInfo.getString("city"));
            tradeAddress.setCounty(updateInfo.getString("county"));
            tradeAddress.setContactName(updateInfo.getString("contactName"));
            tradeAddress.setContactMobile(updateInfo.getString("contactMobile"));
            tradeAddress.setContactAddress(updateInfo.getString("contactAddress"));
            m.put("province",updateInfo.getString("province"));
            m.put("city",updateInfo.getString("city"));
            m.put("county",updateInfo.getString("county"));
            m.put("contactName",updateInfo.getString("contactName"));
            m.put("contactMobile",updateInfo.getString("contactMobile"));
            m.put("contactAddress",updateInfo.getString("contactAddress"));
            int tradeAddressId = tradeAddressDomain.insertTradeAddress(tradeAddress);
            if(tradeAddressId == 0){
                throw new ApolloException(MessageEnum.TRADE_ADDRESS_ADD_FAILURE);
            }
        }
        //更新其他信息
        if("other".equals(updateType)){
            m.put("serviceRemark",updateInfo.getString("serviceRemark"));
        }
        return super.getMasterJdbc().update("trade.TradeMapper.updateTrade",m);
    }

    /**更新订单状态
     * @param tradeId
     * @param status
     * @param serviceRemark
     * @param lastUpdateUserId
     * @return*/
    public boolean updateTradeStatus(int tradeId,String status,String serviceRemark,int lastUpdateUserId){
        Map m = Maps.newHashMap();
        m.put("id",tradeId);
        m.put("status",status);
        //S待付款D待发货R已发货E已完成C已取消G退款中F已退款N退款失败
        if("E".equals(status)||"F".equals(status)||"N".equals(status)){
            m.put("endDate",new Date());//结束时间
        }
        m.put("serviceRemark",serviceRemark);
        m.put("lastUpdateDate",new Date());
        if(lastUpdateUserId==-1){

        }
        m.put("lastUpdateUserId",lastUpdateUserId);
        int num = super.getMasterJdbc().update("trade.TradeMapper.updateTradeStatus",m);
        if(num == 0){
            throw new ApolloException(MessageEnum.ERROR_TRADE_DETAILS_UPDATE);
        }else{
            return true;
        }
    }

    /**更新订单支付状态
     * @param id
     * @param tradeNo
     * @param transactionNo
     * @param transactionAccount
     * @param payStatus
     * @param realPrice
     * @param status
     * @param serviceRemark
     * @param lastUpdateUserId
     * @return*/
    public boolean updateTradePayStatus(int id,String tradeNo, String transactionNo, String transactionAccount,
                                    String payStatus, BigDecimal realPrice,
                                    String status, String serviceRemark,
                                    int lastUpdateUserId){
        Map m = Maps.newHashMap();
        m.put("id",id);
        m.put("lastUpdateUserId",lastUpdateUserId);
        m.put("lastUpdateDate",new Date());
        m.put("transactionNo",transactionNo);
        m.put("transactionAccount",transactionAccount);
        m.put("payStatus",payStatus);
        m.put("payDate",new Date());
        m.put("realPrice",realPrice);
        m.put("status",status);
        m.put("serviceRemark",serviceRemark);
        tradeDetailsDomain.updateTradeDetailsStatusByTrandNo(tradeNo,status);
        int num = super.getMasterJdbc().update("trade.TradeMapper.updateTradePayStatus",m);
        if(num == 0){
            throw new ApolloException(MessageEnum.ERROR_TRADE_PAY_STATUS_UPDATE);
        }else{
            return true;
        }
    }

    /**根据订单号查询订单基本信息,不含商品，用于单表操作
     * @param tradeNo
     * @return*/
    public TradeSummary selectTradeByTradeNo(String tradeNo){
        Map m = Maps.newHashMap();
        m.put("tradeNo",tradeNo);
        return super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeByTradeNo",m);
    }

    /**根据订单id查询订单信息，不含商品，用于单表操作
     * @param id
     * @return*/
    public TradeSummary selectTradeById(int id){
        Map m = Maps.newHashMap();
        m.put("id",id);
        return super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeById",m);
    }

    /**根据条件查询订单基本信息，不含商品，用于单表操作
     * @param m
     * @param pageNum
     * @param pageSize
     * @return*/
    public List<TradeSummary> selectPageBreakByCondition(Map m, int pageNum, int pageSize){
        if(pageNum<0||pageSize>50||pageSize<0){
            throw new ApolloException(MessageEnum.PARMA_RANGE_ERROR);
        }
        m.put("start",(pageNum-1)*pageSize);
        m.put("pageSize",pageSize);
        return super.getSlaveJdbc().selectList("trade.TradeMapper.selectPageBreakByCondition",m);
    }

    /**根据条件查询订单详细信息，用于显示订单列表，订单详细信息等（API使用）
     * @param m
     * @param pageNum
     * @param pageSize
     * @return*/
    public List<TradeVo> selectTradeVoPageBreakByCondition(Map m, int pageNum, int pageSize){
        if(pageNum<0||pageSize>50||pageSize<0){
            throw new ApolloException(MessageEnum.PARMA_RANGE_ERROR);
        }
        m.put("start",(pageNum-1)*pageSize);
        m.put("pageSize",pageSize);
        List<TradeSummary> tradeSummaryList = super.getSlaveJdbc().selectList("trade.TradeMapper.selectPageBreakByCondition",m);
        List<TradeVo> list = new ArrayList<>();
        for(TradeSummary tradeSummary:tradeSummaryList){
            TradeVo tradeVo = new TradeVo();
            tradeVo.setTradeSummary(tradeSummary);
            List<TradeDetails> tradeDetailsList = tradeDetailsDomain.selectTradeDetailsByTradeNo(tradeSummary.getTradeNo());
            tradeVo.setTradeDetailsList(tradeDetailsList);
            list.add(tradeVo);
        }
        return list;
    }

    /**根据条件查询订单详细信息，用于显示订单列表，订单详细信息等（后台管理使用）
     * @param start
     * @param pageSize
     * @param map
     * @return
     */
    public List<TradeVo> getManagerTradeList(int start, int pageSize,Map map){
        Map m = Maps.newHashMap();
        m.putAll(map);
        if(start<0||pageSize>50||pageSize<0){
            throw new ApolloException(MessageEnum.PARMA_RANGE_ERROR);
        }
        m.put("start",start);
        m.put("pageSize", pageSize);
        List<TradeSummary> tradeSummaryList = super.getSlaveJdbc().selectList("trade.TradeMapper.selectPageBreakByCondition",m);
        List<TradeVo> list = new ArrayList<>();
        for(TradeSummary tradeSummary:tradeSummaryList){
            TradeVo tradeVo = new TradeVo();
            tradeVo.setTradeSummary(tradeSummary);
            List<TradeDetails> tradeDetailsList = tradeDetailsDomain.selectTradeDetailsByTradeNo(tradeSummary.getTradeNo());
            tradeVo.setTradeDetailsList(tradeDetailsList);
            list.add(tradeVo);
        }
        return list;
    }

    /**根据条件查询统计数量，配合getManagerTradeList使用
     * @param map
     * @return
     */
    public int getManagerTradeListNum(Map map){
        int total = super.getSlaveJdbc().selectOne("trade.TradeMapper.selectPageBreakByConditionCount",map);
        return total;
    }
    /**获取订单详细信息（根据用户id和订单id，API使用）
     * @param userId
     * @param id
     * @return*/
    public TradeVo selectTradeVoByIdAndUserId(int userId,int id){
        Map m = Maps.newHashMap();
        m.put("id",id);
        m.put("userId",userId);
        TradeSummary tradeSummary = super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeByIdAndUserId",m);
        if(tradeSummary == null){
            throw new ApolloException(MessageEnum.ERROR_TRADE_NOT_FOUND);
        }
        TradeVo tradeVo = new TradeVo();
        tradeVo.setTradeSummary(tradeSummary);
        List<TradeDetails> tradeDetailsList = tradeDetailsDomain.selectTradeDetailsByTradeNo(tradeSummary.getTradeNo());
        tradeVo.setTradeDetailsList(tradeDetailsList);
        List<TradeRefund> tradeRefundList = tradeRefundDomain.selectTradeRefundByTradeNo(tradeSummary.getTradeNo(),"manager");
        tradeVo.setTradeRefundList(tradeRefundList);
        return tradeVo;
    }
    /**获取订单详细信息（根据订单id，后台管理使用）
     * @param id
     * @return*/
    public TradeVo selectTradeAllInfoById(int id){
        TradeSummary tradeSummary = super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeById",id);
        if(tradeSummary == null){
            throw new ApolloException(MessageEnum.ERROR_TRADE_NOT_FOUND);
        }
        TradeVo tradeVo = new TradeVo();
        tradeVo.setTradeSummary(tradeSummary);
        List<TradeDetails> tradeDetailsList = tradeDetailsDomain.selectTradeDetailsByTradeNo(tradeSummary.getTradeNo());
        tradeVo.setTradeDetailsList(tradeDetailsList);
        List<TradeRefund> tradeRefundList = tradeRefundDomain.selectTradeRefundByTradeNo(tradeSummary.getTradeNo(),"api");
        tradeVo.setTradeRefundList(tradeRefundList);
        return tradeVo;
    }

    /**获取订单基本信息（根据用户id，订单id，API使用）
     * @param userId
     * @param id
     * @return
     */
    public TradeSummary selectTradeByIdAndUserId(int userId,int id){
        Map m = Maps.newHashMap();
        m.put("id",id);
        m.put("userId",userId);
        TradeSummary tradeSummary = super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeByIdAndUserId",m);
        if(tradeSummary == null){
            throw new ApolloException(MessageEnum.ERROR_TRADE_NOT_FOUND);
        }
        return tradeSummary;
    }
    public List<TradeSummary> selectPayTimeOutTrades(int time){
        Map map = Maps.newHashMap();
        map.put("createDate",org.apache.commons.lang.time.DateUtils.addMinutes(new Date(),time));
        return super.getSlaveJdbc().selectList("trade.TradeMapper.selectPayTimeOutTrades",map);
    }

    /**更改支付类型，用于继续支付 获取支付参数时更新，目的在于账务审计和退款时知道支付方式
     * @param id
     * @param payType
     * @return*/
    public boolean updateTradePayType(int id,int payType){
        Map m = Maps.newHashMap();
        m.put("id",id);
        m.put("payType",payType);
        int num = super.getMasterJdbc().update("trade.TradeMapper.updateTradePayType",m);
        if(num == 0){
            throw new ApolloException(MessageEnum.ERROR_TRADE_PAY_TYPE_UPDATE);
        }else{
            return true;
        }
    }

    /**
     * @param tradeNo
     * @return
     */
    public TradeVo selectTradeAllInfoByTradeNo(String tradeNo){
        Map m = Maps.newHashMap();
        m.put("tradeNo",tradeNo);
        TradeSummary tradeSummary = super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeByTradeNo",m);
        if(tradeSummary == null){
            throw new ApolloException(MessageEnum.ERROR_TRADE_NOT_FOUND);
        }
        TradeVo tradeVo = new TradeVo();
        tradeVo.setTradeSummary(tradeSummary);
        List<TradeDetails> tradeDetailsList = tradeDetailsDomain.selectTradeDetailsByTradeNo(tradeSummary.getTradeNo());
        tradeVo.setTradeDetailsList(tradeDetailsList);
        List<TradeRefund> tradeRefundList = tradeRefundDomain.selectTradeRefundByTradeNo(tradeSummary.getTradeNo(),"manager");
        tradeVo.setTradeRefundList(tradeRefundList);
        return tradeVo;
    }

    public TradeVo selectTradeAllInfoByTradeNo(int tradeRefundId,String tradeNo){
        Map m = Maps.newHashMap();
        m.put("tradeNo",tradeNo);
        TradeSummary tradeSummary = super.getSlaveJdbc().selectOne("trade.TradeMapper.selectTradeByTradeNo",m);
        if(tradeSummary == null){
            throw new ApolloException(MessageEnum.ERROR_TRADE_NOT_FOUND);
        }
        TradeVo tradeVo = new TradeVo();
        tradeVo.setTradeSummary(tradeSummary);
        List<TradeDetails> tradeDetailsList = tradeDetailsDomain.selectTradeDetailsByTradeNo(tradeSummary.getTradeNo());
        tradeVo.setTradeDetailsList(tradeDetailsList);
        TradeRefund tradeRefund = tradeRefundDomain.selectTradeRefundById(tradeRefundId,"manager");
        List<TradeRefund> tradeRefundList = new ArrayList<>();
        tradeRefundList.add(tradeRefund);
        tradeVo.setTradeRefundList(tradeRefundList);
        return tradeVo;
    }
}
